<template lang="pug">
  .drag-uploader
    FileUpload.d-none(:input-id="fileElId" ref="upload" v-model="files" :drop="true" :multiple="true" @input-file="inputFile" :thread="threadNumber")
    div(v-show="uploader && uploader.dropActive" class="drop-active")
      h3 拖拽文件上传
    v-hover(v-slot:default="{ hover }")
      v-card(:elevation="hover ? 16 : 2" role="button" :for="fileElId")
        v-card-text.text-center.pa-0
          label.white--text.v-btn.theme--light.elevation-2.v-size--default.deep-purple.accent-4( style="width:100%;" :for="fileElId" role="button") 点击拖拽文件到这里
    CandidateFileList(ref="candidateFileList" :files="files", @remove="remove")
    .py-2
      v-btn( color="primary" v-show="!uploader || !uploader.active" @click.prevent="start" type="button" :disabled="onceClickGuard") 开始上传
      v-btn( color="error" v-show="uploader && uploader.active" @click.prevent="cancel" type="button") 停止上传
</template>

<script lang="ts">
  import Vue, {VueConstructor} from 'vue'
  import FileUpload from 'vue-upload-component'
  import fileUploadEventHandler, {FileUploadFile} from '@/components/widgets/file_uploader/FileUploadEventHandler'
  import CandidateFileList from '@/components/widgets/file_uploader/CandidateFileList.vue'
  import {url} from '@/store/utils'
  import _ from 'lodash'

  export default (Vue as VueConstructor<Vue & {
    uploader: FileUpload,
    onceClickGuard: boolean,
    $refs: {
      upload: FileUpload,
      candidateFileList: CandidateFileList
    }
  }>).extend({
    name: 'file_uploader',
    props: {
      attachableType: String,
      attachableId: Number
    },
    methods: {
      inputFile(newFile: FileUploadFile, oldFile: FileUploadFile) {
        fileUploadEventHandler(newFile, oldFile, this)
      },
      remove(file: FileUploadFile) {
        this.$refs.upload.remove(file)
      },
      onFileUploadSuccess: _.debounce(function(){
        this.$emit('refresh')
      }, 800),
      async start() {
        if (this.onceClickGuard) {
          return
        }
        try {
          this.onceClickGuard = true
          this.$refs.candidateFileList.toggleLoading()
          // TODO get default upload target
          var postData = { attachable_id: this.attachableId, attachable_type: this.attachableType }
          var response = await axios.post(url('/api/get-upload-policy'), postData)
          this.$refs.candidateFileList.toggleLoading()
          var config = response.data.config
          // this.postActionUrl = config.host
          this.files.forEach((file: any) => {
            var data = {}

            if (Object.keys(config['callback-var']).length) {
              for (const [key, value] of Object.entries(config['callback-var'])) {
                data[key] = value
              }
            }
            file.postAction = config.host
            data.policy = config.policy
            data.OSSAccessKeyId = config.accessid
            data.signature = config.signature
            data.host = config.host
            data.callback = config.callback
            data.key = config.dir + file.file.name || file.name
            file.data = data
          })
          this.uploader.active = true
        } catch (err) {
          alert(err)
        } finally {
          this.onceClickGuard = false
        }
      },
      cancel() {
        this.uploader.active = false
      },
    },
    computed: {
      fileElId() {
        return `file_${this._uid}`
      }
    },
    data() {
      return {
        threadNumber: 5,
        onceClickGuard: false,
        uploader: null as FileUpload | null,
        files: [] as FileUploadFile[]
      }

    },
    components: { FileUpload, CandidateFileList },
    mounted(): void {
      this.uploader = this.$refs.upload
    }
  })
</script>

<style scoped>
  .drag-uploader .drop-active {
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    position: fixed;
    z-index: 999999;
    opacity: .6;
    text-align: center;
    background: #000;
  }
</style>